在上一篇文章中我們提到了 ConfigMap
這個 Kubernetes
讓我們解耦程式碼複雜度以及統一管理設定檔的好工具,但由於 ConfigMap
是使用明碼儲存一些不敏感的資料,那我們的 API Key
和 金鑰
等敏感資料就不太適合了呢。於是 Kubernetes
提供我們另一種選擇 - Secret
類似於 ConfigMap
的使用方式但他能對敏感資料有多一層保護而不會隨便暴露,但有趣的是 Secret
某方面來說也不是像是字面上的那麼安全,下面我們將會簡單談到他的運作原理。
Secret
與 ConfigMap
在基本操作上大致相同,但在使用的方面不太一樣,所以這裡來特別提一下兩者比較不同的地方。Secret
是 Kubernetes
提供開發者存放敏感資料的方式, Kubernetes
本身也使用了相同的機制來存放 Access Token
,並限制 API 的存取權限,確保不會有外部服務隨意操作。
Secret
大致有三種類型:
Service Account
:由 k8s 自動建立並掛載到 Pod,用來存取 Kubernetes
API 使用,你可以在 /run/secret/kubernetes.io/serviceaccount
目錄中找到。Opaque
:以 base64 編碼的 Secret,用來儲存 密碼、金鑰等等。docker-registry
:如果映像檔是放在私有的 Registry,就需要使用這種類型的 Secret
。在 Kubernetes
存取資料有以下幾種常見的方式:
Secret
當作環境變數使用。Secret File
掛載在 Pod
中的某個路徑下面使用。Pod
中加入 docker-registry secret
讓我們不用在拉取私人庫時都需要先 docker login
,簡單來說是儲存 docker login
的帳號密碼讓 Kubernetes
可以自動登入順利運作。在建立 Secret
的值時,我們都要必須先使用 base64
進行轉碼,而 Kubernetes
在我們正確掛載後會自動幫我們解碼回原本的值。
將 Secret
轉換為 base64
:
首先我們可以使用內建語法取得經過 base64
的字串
echo -n 'my-account' | base64
echo -n 'my-password' | base64
----------
bXktYWNjb3VudA==
bXktcGFzc3dvcmQ=
於是我們獲得了以上的 bXktYWNjb3VudA==
bXktcGFzc3dvcmQ=
做為加密過的字串。
創建 yaml 設定檔:
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYWNjb3VudA==
password: bXktcGFzc3dvcmQ=
kubectl apply -f secret.yaml
----------
secret/test-secret created
查看一下結果:
kubectl get secret test-secret
----------
NAME TYPE DATA AGE
test-secret Opaque 2 15s
kubectl describe secret test-secret
----------
Name: test-secret test-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 11 bytes
username: 10 bytes
可以在 Data 內看到 Secret
的 key 值和 base64
加密後的大小。
或者你想只使用 kubectl
創建:
kubectl create secret generic test-secret --from-literal='username=my-account' --from-literal='password=my-password'
這裡一樣使用了 create 當作創建資源的聲明指令,並且還需要加上 generic
這個 subcommand
表示我們要使用本地資源或者是 key-value 創建 Secret
。
讓我們利用上面建立的 Secret
來實際測試:
# secret-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secret-volume
volumes:
- name: secret-volume
secret:
secretName: test-secret
創建 Pod 並查看:
kubectl apply -f secret-test-pod.yaml
-----------
pod/secret-test-pod createde
kubectl get pod secret-test-pod
------------
NAME READY STATUS RESTARTS AGE
secret-test-pod 1/1 Running 0 57s
進入 Pod 中查看:
kubectl exec -it secret-test-pod -- sh
在容器中打印出 Secret
內容
ls /etc/secret-volume
------------
password username
cat /etc/secret-volume/username
------------
my-account
cat /etc/secret-volume/password
------------
my-password
成功打印出 base64
解碼後的數值~
經過上面的介紹後,可能有人已經可以察覺到,我們可以非常容易的看到 Secret
的原碼,只要有相關的權限即可,雖然他的內容經過了 base64
編碼,但基本上等同於明文。
所以說, Kubernetes
原生的 Secret
是非常簡單的,不是特別適合在大公司直接使用,對 RBAC(角色權限)
的挑戰也比較大。
針對上面提到的問題,其大概的解決方案不難想到如下幾種,etcd加密、API Server 嚴格權限限制以及強化 Node 權限管理以及系統安全,並且以上的方案都需要缺一不可,如此看來,我們需要付出非常繁重的成本才能讓原生 Secret
在嚴謹條件下達到保障。
所以社群以及雲端服務商都有提供一些解套方案讓我們可以參考一下:
因為沒有實際操作過,這裡就先點到為止,主要目的是可以讓大家從另一個角度去思考一個工具的利弊以及取捨,接下來我們還會繼續介紹其他常用的 Volume
類別,敬請期待~
千呼萬喚始出來!鐵人賽系列「從異世界歸來發現只剩自己不會 Kubernetes」同名改編作品出版了!
感謝所有交流指教的各路英雄,也感謝願意點閱文章的各位,如果能幫助到任何人都將會是我的榮幸。
本書內容改編自第 14 屆 iThome 鐵人賽 DevOps 組的優選系列文章《從異世界歸來發現只剩自己不會 Kubernetes》。此書是一本綜合性的指南,針對想要探索認識 Kubernetes 的技術人員而生。無論是初涉此領域的新手,還是已有深厚經驗的資深工程師,本書都能提供你所需的知識和技能。
「這本書不僅提供了豐富的範例程式碼和操作指南,讓身為工程師的我們能實際操作來加深認知;更重要的是,它教會我如何從後端工程師的角度去思考和應用 Kubernetes。從容器的生命週期、資源管理到部署管理,每一章都與我們的日常開發工作息息相關。」
──── 雷N │ 後端工程師 / iThome 鐵人賽戰友
天瓏連結: 從異世界歸來發現只剩自己不會 Kubernetes:初心者進入雲端世界的實戰攻略!
相關文章:
相關程式碼同時收錄在:
https://github.com/MikeHsu0618/2022-ithelp/tree/master/Day19
Reference
[Day 12] 敏感的資料怎麼存在k8s?! - Secrets
Kubernetes 那些事 — ConfigMap 與 Secrets